package at.irian.jsfatwork.web.model;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.core.annotation.Order;
import org.apache.myfaces.shared_tomahawk.util.MessageUtils;

import at.irian.jsfatwork.web.model.ValidatorException;

import javax.faces.application.FacesMessage;
import javax.faces.event.AbortProcessingException;
import javax.faces.context.FacesContext;
import javax.faces.component.UIComponent;

/**
 * @author Thomas Spiegl, IRIAN Solutions GmbH
 */
@Aspect
@Order(value = 0)
public class ValidatorExeptionAspect {

    @Around("execution(public * at.irian.jsfatwork.web.model.*.save(..))")
    public Object checkForValdiationException(ProceedingJoinPoint pjp) throws Throwable {
        try {
            return pjp.proceed();
        } catch (Exception e) {  // catch all Excptions
            if (e instanceof ValidatorException) {
                registerFacesMessages((ValidatorException) e);
            } else {
                addMessage(e.getMessage(), null);
            }
            return null;
        }
    }

    @Around("execution(public * at.irian.jsfatwork.web.model.*.validate(..))")
    public Object checkForValdiationExceptionOnAction(ProceedingJoinPoint pjp) throws Throwable {
        try {
            return pjp.proceed();
        } catch (ValidatorException e) { // just catch ValidatorException
            registerFacesMessages(e);
            throw new AbortProcessingException(); // abort event processing
        }
    }

    private void registerFacesMessages(ValidatorException e) {
        for(ValidatorMsg msg : e.getMessages()) {
            addMessage(msg.getMsg(), msg.getClientid());
        }
    }

    private void addMessage(String msg, String clientId) {
        if (clientId == null) {
            UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent("cform:error");
            if (component != null) {
                clientId = component != null ? component.getClientId(FacesContext.getCurrentInstance()) : null;
            } else {
                // TODO warning
            }
        }
        MessageUtils.addMessage(FacesMessage.SEVERITY_ERROR, msg, null, clientId);
    }
}